using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Media;
using System;
using SuperPongControl;
using WindowsGame1;


public partial class SuperPong : Game
{
    static void Main()
    {
        SuperPong game = new SuperPong();
        game.Run();
    }
    
    SuperPong()
    {
        gdm = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
        this.Window.AllowUserResizing = true;
        this.Window.ClientSizeChanged += new EventHandler<EventArgs>(onClientSizeChange);
        this.Window.Title = "Particle Pong";
        inputHandler = new InputHandler();
    }

    void onClientSizeChange(object sender, EventArgs e)
    {
        onclientSizeChange();
    }

    void onclientSizeChange()
    {
        int Height = this.GraphicsDevice.PresentationParameters.BackBufferHeight;
        gdm.PreferredBackBufferWidth = (int)(Height * 1.5f);
        gdm.PreferredBackBufferHeight = Height;
        gdm.ApplyChanges();
        float Aspect = (float)this.Window.ClientBounds.Width / (float)Height;
        if (Aspect == 0)
        {
            Aspect = 2f;
        }
        gdm.PreferredBackBufferWidth = (int)(Height * Aspect) +100;
        gdm.ApplyChanges();
        for (int i = 0; i < numPlayers; i++)
        {
            Players[i].SetScale(Height);
            Players[i].Aspect = Aspect;
        }
        this.CurrAspect = Aspect;
        this.Scale = Height;
        ball.SetScale(Height);
        ball.Aspect = Aspect;
        

        MainMenu.Scale = Height;
        BackMenu.Scale = Scale;
        NumPlayersMenu.Scale = Scale;
        LifeSelectMenu.Scale = Scale;
        DifficultyMenu.Scale = Scale;
        GameEndMenu.Scale = Scale;

        MainMenu.Aspect = Aspect;
        BackMenu.Aspect = Aspect;
        NumPlayersMenu.Aspect = Aspect;
        LifeSelectMenu.Aspect = Aspect;
        DifficultyMenu.Aspect = Aspect;
        GameEndMenu.Aspect = Aspect;
        
    }

    

    /* Resources */
    SpriteFont TitleFont;

    Song BackgroundMusic;
    SoundEffect DeadSound;
    SoundEffect BounceSound;

    Texture2D ParticleBase;
    Texture2D PaddleBase;
    Texture2D MainPong;
    Texture2D MainInstructions;
    Texture2D MainCredits;
    Texture2D MainLives;
    Texture2D MainDifficulty;
    Texture2D MainGamemode;
    Texture2D MainGameOver;
    Texture2D CreditPage;
    Texture2D InstructionPage;

    /* End Resources */

    /* Menus */
    ListMenu MainMenu;
    ListMenu BackMenu;
    ListMenu NumPlayersMenu;
    ListMenu LifeSelectMenu;
    ListMenu DifficultyMenu;
    ListMenu GameEndMenu;
    /* End Menus */

    
    GraphicsDeviceManager gdm;
    SpriteBatch spriteBatch;
    SpriteBatch particleSpriteBatch;
    int gameState = SuperPongControl.Types.GameState.MAIN_MENU;    // Start at main menu
    Player[] Players = new Player[4];       // Reserve memory for 4 players
    
    Ball2 ball;
    int numPlayers = 2;                     // Set the default number of players at 2
    int numLives = 3;                       // The number of lives each player gets at the beginning
    float Difficulty = 3;
    GameTime gameTime;                      // Make gameTime available to all methods
    const float TwoPlayerAspect = 1.5f;
    const float FourPlayerAspect = 1.0f;
    int Scale = 600;
    float CurrAspect = 1.5f;
    ParticleSystem pSystem;
    bool Paused = false;
    float creditopentime;
    float instructionsopentime;
    InputHandler inputHandler;

    ConnectionManager cm = null;

    protected override void Initialize()
    {
        base.Initialize();
        this.IsMouseVisible = true;
        //  Initialize players
        for (int i = 0; i < 4; i++)
        {
            Players[i] = new Player(i, new Vector2(this.GraphicsDevice.Viewport.Width+100, this.GraphicsDevice.Viewport.Height), this.particleSpriteBatch, PaddleBase, ParticleBase);
            Players[i].Aspect = this.CurrAspect;
            Players[i].Init();
        }
        //ball = new Ball(this.particleSpriteBatch, this.ParticleBase, new Vector2(this.GraphicsDevice.Viewport.Width, this.GraphicsDevice.Viewport.Height), Players, DeadSound, BounceSound);
        ball = new Ball2(this.particleSpriteBatch, this.ParticleBase, new Vector2(this.GraphicsDevice.Viewport.Width, this.GraphicsDevice.Viewport.Height), Players, DeadSound, BounceSound);
        ball.Aspect = this.CurrAspect;
        ball.PausedFont = TitleFont;

        if (cm == null)
        {
            cm = new ConnectionManager();
            cm.startServer();
        }

        MediaPlayer.Play(BackgroundMusic);
        MediaPlayer.IsRepeating = true;

        // Initialize Menus
        MainMenu = new ListMenu(TitleFont, spriteBatch,2, new Vector2(0.4f, 0.25f), Scale, CurrAspect);
        MainMenu.EditItem(0, "Start");
        //MainMenu.EditItem(1, "Instrukcje");
        //MainMenu.EditItem(1, "Opcje");
        MainMenu.EditItem(1, "Koniec");
        
        BackMenu = new ListMenu(TitleFont, spriteBatch, 1, new Vector2(0.05f, 0.9f), Scale, CurrAspect);
        BackMenu.EditItem(0, "Do Menu Startowego");
       
        NumPlayersMenu = new ListMenu(TitleFont, spriteBatch, 2, new Vector2(0.4f, 0.2f), Scale, CurrAspect);
        NumPlayersMenu.EditItem(0, "1 Gracz");
        NumPlayersMenu.EditItem(1, "2 Graczy");
       
        LifeSelectMenu = new ListMenu(TitleFont, spriteBatch, 4, new Vector2(0.4f, 0.2f), Scale, CurrAspect);
        LifeSelectMenu.EditItem(0, "3 Szanse");
        LifeSelectMenu.EditItem(1, "5 Szanse");
        LifeSelectMenu.EditItem(2, "10 Szanse");
        LifeSelectMenu.EditItem(3, "15 Szanse");
       
        DifficultyMenu = new ListMenu(TitleFont, spriteBatch, 5, new Vector2(0.4f, 0.2f), Scale, CurrAspect);
        DifficultyMenu.EditItem(0, "Spokojny");
        DifficultyMenu.EditItem(1, "Normalny");
        DifficultyMenu.EditItem(2, "Trudny");
        DifficultyMenu.EditItem(3, "Ekstremalny");
        DifficultyMenu.EditItem(4, "Legendarny");
     
        GameEndMenu = new ListMenu(TitleFont, spriteBatch, 2, new Vector2(0.4f, 0.2f), Scale, CurrAspect);
        GameEndMenu.EditItem(0, "Restart");
        GameEndMenu.EditItem(1, "Menu Startowe");
        
        onclientSizeChange();

        pSystem = new ParticleSystem(new Vector2(0,0));
        pSystem.AddEmitter(new Vector2(0.001f, 0.0015f),
                                    new Vector2(0, -1),
                                    new Vector2((float)(-0.128f * Math.PI * 4), (float)(0.128f * Math.PI * 4)),
                                    new Vector2(0.75f, 1.0f),
                                    new Vector2(0.125f, 0.18f),
                                    new Vector2(0.067f, 0.12f),
                                    Color.White, Color.Orange, Color.Orange, Color.Orange,
                                    new Vector2(0.60f, 0.80f),
                                    new Vector2(0.20f, 0.30f),
                                    1000, Vector2.Zero, ParticleBase);
        pSystem.Position = new Vector2(-0.2f, 1.05f);
        pSystem.Position = new Vector2(CurrAspect+0.2f, 1.05f);

      
       
        
        
    }

    protected override void LoadContent()
    {
        spriteBatch = new SpriteBatch(this.GraphicsDevice);
        particleSpriteBatch = new SpriteBatch(this.GraphicsDevice);
        //  Load Fonts
        this.TitleFont = Content.Load<SpriteFont>("TitleFont");

        //  Load Sprites
        this.ParticleBase = Content.Load<Texture2D>("ParticleBase1");
        this.PaddleBase = Content.Load<Texture2D>("paddle1");
        this.MainPong = Content.Load<Texture2D>("particlepong");
        this.MainInstructions = Content.Load<Texture2D>("instructions");
       
        this.MainDifficulty = Content.Load<Texture2D>("difficulty");
        this.MainGamemode = Content.Load<Texture2D>("gamemode");
        this.MainLives = Content.Load<Texture2D>("lives");
        this.MainGameOver = Content.Load<Texture2D>("gameover");
        //this.CreditPage = Content.Load<Texture2D>("creditpage");
        this.InstructionPage = Content.Load<Texture2D>("instructionpage");

        //  Load Sounds
        this.BackgroundMusic = Content.Load<Song>("pingpongsong");
        this.DeadSound = Content.Load<SoundEffect>("Dead");
        this.BounceSound = Content.Load<SoundEffect>("Bounce");

    }

    protected override void Update(GameTime gameTime)
    {
        
        this.gameTime = gameTime;
       
             
        handleKeyInput();
        if (gameState == SuperPongControl.Types.GameState.GAME_RUNNING && !Paused)
        {
            ball.Update(gameTime.ElapsedGameTime.Milliseconds / 1000f);
            int AlivePlayers = numPlayers;
            for (int i = 0; i < numPlayers; i++)
            {
                Players[i].Update(gameTime.ElapsedGameTime.Milliseconds / 1000f, ball.Position, ball.Direction);
                if (Players[i].Lives < 1)
                {
                    AlivePlayers--;
                }
            }
            if (AlivePlayers <= 1)
            {
                if (Players[1].Lives > 0)
                {
                    pSystem.EmitterList[0].StartColor1 = Color.White;
                    pSystem.EmitterList[0].StartColor2 = Color.DarkBlue;
                    pSystem.EmitterList[0].EndColor1 = Color.RoyalBlue;
                    pSystem.EmitterList[0].EndColor2 = Color.RoyalBlue;
                }
                else
                {
                    pSystem.EmitterList[0].StartColor1 = Color.White;
                    pSystem.EmitterList[0].StartColor2 = Color.Orange;
                    pSystem.EmitterList[0].EndColor1 = Color.Orange;
                    pSystem.EmitterList[0].EndColor2 = Color.Orange;
                }
                this.gameState = SuperPongControl.Types.GameState.GAME_END;
                pSystem.Clear();
                AlivePlayers = numPlayers;
            }

        }
        else
        {
            pSystem.Update((float)gameTime.ElapsedGameTime.Milliseconds / 1000.0f);
        }
 
    }

    protected override void UnloadContent()
    {
    }

    void InitializeGame()
    {
      
        ball.numPlayers = this.numPlayers;
        ball.Restart(numLives);
        this.gameState = SuperPongControl.Types.GameState.GAME_RUNNING;
    }

    public void TogglePause()
    {
        Paused = !Paused;
    }
}